#pragma once 
#include <pthread.h>
#include <vector>
#include "ncurses.h"
#include "Tool.hpp"
#include "ChatClient.hpp"
using namespace std;
class ChatWindows;
class Pram
{
    public:
        Pram(int pthread_num,ChatWindows* cw,ChatClient* cc)
        {
            pthread_num_ = pthread_num;
            cw_ = cw;
            cc_ = cc;
        }
    public:
       int pthread_num_;
       ChatWindows* cw_;
       ChatClient* cc_;
};
class ChatWindows
{
    public:
        ChatWindows()
        {
            pthread_mutex_init(&lock_,NULL);
            head_ = NULL;
            output_ = NULL;
            input_ = NULL;
            user_list_ = NULL;
            vec_.clear();
        }
        ~ChatWindows()
        {
            pthread_mutex_destroy(&lock_);
            if(head_)
            {
                delwin(head_);
            }
            if(output_)
            {
                delwin(output_);
            }
            if(input_)
            {
                delwin(input_);
            }
            if(user_list_)
            {
                delwin(user_list_);
            }
            endwin();
        }
        void Start(ChatClient* cc)
        {
            initscr();
            //四个窗口，四个线程来运行
            for(int i = 0; i < 4; i++)
            {
                Pram* pram = new Pram(i,this,cc);
                pthread_t pid;
                int ret = pthread_create(&pid,NULL,RunWindows,(void*)pram);
                if(ret < 0)
                {
                    LOG(ERROR,"pthread create filad") << endl;
                    return;
                }
                vec_.push_back(pid);
            }
            //主线程等待所有的线程结束
            for(size_t i = 0;i < vec_.size();i++)
            {
                pthread_join(vec_[i],NULL);
            }
        }
        static void* RunWindows(void* arg)
        {
           Pram* pram = (Pram*)arg;
           ChatWindows* cw = pram->cw_;
           ChatClient* cc = pram->cc_;
           if(!cw)
           {
               LOG(INFO,"cw is nullptr") << endl;
               return NULL;
           }
           
           //通过线程来运行进程
           switch(pram->pthread_num_)
           {
               case 0:
                   //头窗口
                   cw->HeadWindow();
                   break;
               case 1:
                   //输出窗口
                   cw->OutputWindow(cc);
                   break;
               case 2:
                   //输入窗口
                   cw->InputWindow(cc);
                   break;
               case 3:
                   //用户列表窗口
                   cw->UserlistWindow(cc);
                   break;
           }

        }

        void UserlistWindow(ChatClient* cc)
        {
            WINDOW* old_list = NULL;
            while(1)
            {
                user_list_ = newwin((3*LINES)/5,COLS/4,LINES/5,(3*COLS)/4);
                box(user_list_,0,0);
                Refresh(user_list_);
                if(old_list)
                {
                    delwin(old_list);
                }
                vector<UdpMsg> vec_ = cc->GetVec();
                for(size_t i = 0;i < vec_.size();i++)
                {
                    string user_msg;
                    user_msg += vec_[i].nick_name_;
                    user_msg += "-";
                    user_msg += vec_[i].school_;
                    mvwaddstr(user_list_,i+1,1,user_msg.c_str());
                    Refresh(user_list_);
                }
                old_list = user_list_;

                sleep(1);
            }
        }

        void InputWindow(ChatClient* cc)
        {
            WINDOW* old_input = NULL;
            //输入框
            //客户端发送到服务端
            while(1)
            {
                input_ = newwin(LINES/5,COLS,(4*LINES)/5,0);
                box(input_,0,0);
                Refresh(input_);
                if(old_input)
                {
                    delwin(old_input);
                }
                //提示语
                string tips = "please input msg# ";
                mvwaddstr(input_,1,1,tips.c_str());
                Refresh(input_);
                //输入的代码
                char buf[UDP_COUNT] = {0};
                wgetnstr(input_,buf,sizeof(buf)-1);
                UdpMsg um;
                um.nick_name_ = cc->GetMe().nick_name_;
                um.school_ = cc->GetMe().school_;
                um.user_id_ = cc->GetMe().user_id_;
                um.msg_.assign(buf,strlen(buf));
                string send_msg;
                um.Serialize(&send_msg);
                cc->SendMsg(send_msg);
                old_input = input_;
            }
        }
        
        void DrowOutput()
        {
            //绘制
            output_ = newwin((3*LINES)/5,(3*COLS)/4,LINES/5,0);
            box(output_,0,0);
            Refresh(output_);
            
        }

        void OutputWindow(ChatClient* cc)
        {
            int line = 1;
            string recv_msg;
            DrowOutput();
            int x,y;
            getmaxyx(output_,y,x);
            while(1)
            {
                recv_msg.clear();
                //客户端接收服务端的消息
                cc->RecvMsg(&recv_msg);
                if(line >= y-2)
                {
                    DrowOutput();
                    line = 1;
                }
                mvwaddstr(output_,line,1,recv_msg.c_str());
                Refresh(output_);
                line++;
            }

        }

        void Refresh(WINDOW* win)
        {
            pthread_mutex_lock(&lock_);
            wrefresh(win);
            pthread_mutex_unlock(&lock_);
        }
        void HeadWindow()
        {
            WINDOW* old_head = NULL;
            while(1)
            {
                //绘制
                head_ = newwin(LINES/5,COLS,0,0);
                if(old_head)
                {
                    delwin(old_head);
                }
                box(head_,0,0);
                Refresh(head_);
                //欢迎语
                int x,y;
                getmaxyx(head_,y,x);
                string welcome = "welcome to chat system";
                mvwaddstr(head_,y/2,(x-welcome.size())/2,welcome.c_str());
                Refresh(head_);
                old_head = head_;
                sleep(1);
            }
        }  
    private:
        pthread_mutex_t lock_;//互斥锁--保护刷新页面
        //四个窗口句柄
        WINDOW* head_;
        WINDOW* output_;
        WINDOW* input_;
        WINDOW* user_list_;
        //线程号容器
        vector<pthread_t> vec_;
        ChatClient* cc_;
};


